package com.treasuremall.auth.config;

import com.treasuremall.auth.jwt.JwtTokenEnhancer;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

/**
 * 认证服务器配置
 *
 * @author 时前程
 * @create 2020-02-24 22:27
 * @Version V1.0
 **/
@Configuration
@EnableAuthorizationServer
@AllArgsConstructor
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    /**
     * 需要配置这个支持password模式
     */
    private AuthenticationManager authenticationManager;

    private UserDetailsService userDetailsService;

    private TokenStore tokenStore;

    private JwtAccessTokenConverter jwtAccessTokenConverter;

    private JwtTokenEnhancer jwtTokenEnhancer;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
            throws Exception {
        endpoints.tokenStore(tokenStore)
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);
        if (jwtAccessTokenConverter != null && jwtTokenEnhancer != null) {
            TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
            List<TokenEnhancer> enhancerList = new ArrayList<>();
            enhancerList.add(jwtTokenEnhancer);
            enhancerList.add(jwtAccessTokenConverter);
            tokenEnhancerChain.setTokenEnhancers(enhancerList);
            //jwt
            endpoints.tokenEnhancer(tokenEnhancerChain)
                    .accessTokenConverter(jwtAccessTokenConverter);
        }
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()// 使用in-memory存储
                .withClient("ben1")// client_id
                .secret("123456")// client_secret
                .authorizedGrantTypes("authorization_code", "refresh_token", "password")// 该client允许的授权类型
                .scopes("all")// 允许的授权范围
                .accessTokenValiditySeconds(60*60*2)//令牌时间
                .refreshTokenValiditySeconds(60*60*48)//刷新令牌时间
                .autoApprove(false)//true 自动授权 false 手动授权
                //加上验证回调地址
                .redirectUris("http://baidu.com")
                .and()
                .withClient("ben2")
                .secret("123456")
                .authorizedGrantTypes("authorization_code", "refresh_token", "password")
                .scopes("all")
                .autoApprove(false)
                .redirectUris("http://baidu.com");
    }
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                .allowFormAuthenticationForClients()
                //开启/oauth/check_token验证端口无权限访问
                .checkTokenAccess("permitAll()")
               //解决 Encoded password does not look like BCrypt 异常
                .passwordEncoder(NoOpPasswordEncoder.getInstance());
    }
}
